import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt


def Open_Frame_IRV(inpath, frame, width, hight):
    f = open(inpath, "rb")  # rb：也即 binary mode，read()操作返回的是bytes
    # frame  = 10   #irv：32*1024 视频的头，(640*480*2+1024) 一帧的长度
    f.seek(32 * 1024 + (frame - 1) * (hight * width * 2 + 1024), 0)  # 第一个代表需要移动偏移的字节数,0 代表从文件开头开始算起
    ccc = f.read(hight * width * 2)  # python在读取文件的时候是根据光标位置来读取的。读一行以后光标位置到了下一行。再来个read又到了下一行。
    img = np.frombuffer(ccc,
                        dtype='uint16')  # read的数值以bytes的类型保存，通过np.frombuffer方法还原成类型为uint16的ndarray，这种方式还原出来的ndarray是只读的。
    img = img.reshape((hight, width))
    # img=img[:-2,:-2] #去边缘黑边
    # img = np.squeeze(img)
    f.close()
    return img


# 读取视频总帧数
def Read_TotalFrame_IRV(inpath, w, h):
    f = open(inpath, "rb")  # rb：也即 binary mode，read()操作返回的是bytes
    f.seek(0, 2)
    size = f.tell()
    Total_num = int((size - 32 * 1024) / (w * h * 2 + 1024)) - 1
    return Total_num


# 求单帧视频中的最大最小AD值
def FindMaxMin(inpath, frame, width, hight):
    f = open(inpath, "rb")  # rb：也即 binary mode，read()操作返回的是bytes
    # frame  = 10   #irv：32*1024 视频的头，(640*480*2+1024) 一帧的长度
    f.seek(32 * 1024 + (frame - 1) * (hight * width * 2 + 1024), 0)  # 第一个代表需要移动偏移的字节数,0 代表从文件开头开始算起
    ccc = f.read(hight * width * 2)  # python在读取文件的时候是根据光标位置来读取的。读一行以后光标位置到了下一行。再来个read又到了下一行。
    img = np.frombuffer(ccc,
                        dtype='uint16')  # read的数值以bytes的类型保存，通过np.frombuffer方法还原成类型为uint16的ndarray，这种方式还原出来的ndarray是只读的。
    Max = max(img)
    Min = min(img)
    f.close()
    return Max, Min


# 线性拉伸
def imadjust(in_img, low, high):
    out_img = in_img * ((low <= in_img) & (in_img <= high)) + high * (in_img > high) + low * (in_img < low)
    out_img = (out_img - low) / (high - low) * 255
    out_img = np.uint8(out_img)
    return out_img


if __name__ == '__main__':  # 独立运行时测试用
    # test
    w = 640
    h = 480
    inpath = r"E:\infraVideos\20240419\3mm7s50%.IRV"  # IRV格式的原红外视频

    Total_num = Read_TotalFrame_IRV(inpath, w, h)  # 求视频的总帧数
    # Total_num = 200  # 可以自己设定需要分析处理的帧数

    # 坏点坐标
    badPoints = [[0, 0], [0, 2], [0, 3], [0, 4], [0, 5], [0, 6], [0, 7], [0, 8], [0, 9], [0, 12], [0, 13]]
    # 对每一个坐标的时间序列画图
    badPoints_list = [[] for _ in range(len(badPoints))]
    # 全图平均值列表
    mean_list = []
    for i in range(len(badPoints)):
        x = badPoints[i][0]
        y = badPoints[i][1]
        for frame in range(1, Total_num + 1):
            img = Open_Frame_IRV(inpath, frame, width=w, hight=h)
            badPoints_list[i].append(img[x, y])
        print(f"坐标：x = {x} y = {y} 的灰度值为{badPoints_list[i]}")
        print(f"坐标：x = {x} y = {y} 的标准差为{np.std(badPoints_list[i])}")

    for frame in range(1, Total_num + 1):
        img = Open_Frame_IRV(inpath, frame, width=w, hight=h)
        mean = np.mean(img)
        mean_list.append(mean)
    print(f"平均灰度值为{mean_list}")
    # 画出坏点的对比图
    plt.figure(figsize=(10, 6))

    for i, points in enumerate(badPoints_list):
        plt.plot(points, label=f'Point {badPoints[i]}')

    plt.plot(mean_list, color='black', label='mean')

    plt.xlabel('Frame')
    plt.ylabel('AD Value')
    plt.title('AD Value Time Series for Bad Points')
    # 指定纵轴范围
    # plt.ylim(22000, 28000)


    plt.legend()
    plt.show()
